<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>通过 Vue 组件通信实现父组件监听并处理子组件事件</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script>
</head>
<body>
<div id="app">
    <p>Web开发框架：</p>
    <web-framework-list></web-framework-list>
</div>
<script>
    Vue.component('web-framework-list', {
        data: function () {
            return {
                frameworks: [
                    {'name': 'Laravel', 'language': 'php'},
                    {'name': 'Vue', 'language': 'javascript'},
                    {'name': 'Gin', 'language': 'golang'},
                    {'name': 'Flask', 'language': 'python'},
                ],
                languages: [
                    'php', 'golang', 'javascript', 'python'
                ],
            }
        },
        template: '<div>' +
            '<ul>' +
            '<li v-for="framework in sortedFrameworks" :class="framework.language">{{ framework.name }}</li>' +
            '</ul>' +
            '<add-web-framework :frameworks="frameworks" :languages="languages" @framework-added="addFramework"></add-web-framework>' +
            '</div>',
        methods: {
            addFramework(framework, language) {
                this.frameworks.push(
                    {'name': framework, 'language': language}
                );
            }
        },
        computed: {
            sortedFrameworks() {
                return this.frameworks.sort((a, b) => {
                    if (a.language < b.language) {
                        return -1;
                    } else if (a.language > b.language) {
                        return 1;
                    } else {
                        return 0;
                    }
                });
            }
        }
    });
    Vue.component('add-web-framework', {
        props: ['frameworks', 'languages'],
        data: function () {
            return {
                newFramework: '',
                newLanguage: '',
            }
        },
        template: '<div>' +
            '框架：<input v-model="newFramework" name="framework"/> ' +
            '语言: <select v-model="newLanguage"><option v-for="language in languages" v-text="language"></option></select> ' +
            '<button @click="addNewFramework">新增框架</button>' +
            '</div>',
        methods: {
            addNewFramework() {
                let exists = this.frameworks.find(framework => framework.name == this.newFramework);
                if (exists) {
                    alert('该框架已存在！');
                    return;
                }
                this.$emit('framework-added', this.newFramework, this.newLanguage);
            }
        }
    });
    var app = new Vue({
        el: '#app'
    });
</script>
</body>
</html>